import json

from rest_framework import serializers

from common.common_base_model_serializer import BaseModelSerializer, NestedJSONField, BaseNestedFieldsModelSerializer
from .models import *


class ApiInfoModelSerializer(BaseNestedFieldsModelSerializer):
    class Meta:
        model = ApiInfo
        fields = '__all__'


class TestCaseModelSerializer(BaseModelSerializer):
    class Meta:
        model = TestCase
        fields = '__all__'


class ApiSuiteModelSerializer(BaseModelSerializer):
    class Meta:
        model = ApiSuite
        fields = '__all__'


class TestCaseStepModelSerializer(BaseNestedFieldsModelSerializer):
    class Meta:
        model = TestCaseStep
        fields = '__all__'


class TestCaseGroupModelSerializer(BaseModelSerializer):
    # test_case_merge = serializers.ManyRelatedField(many=True, required=False)
    # 多对多的关系下， 入参不校验序列化器使用PrimaryKeyRelatedField 重新定义
    test_case_merge = serializers.PrimaryKeyRelatedField(
        many=True, queryset=TestCase.objects.all(), required=False, allow_null=True
    )

    class Meta:
        model = TestCaseGroup
        fields = '__all__'

    # def create(self, validated_data):
    #     test_case_merge = validated_data.pop('test_case_merge', [])
    #     test_case_group = TestCaseGroup.objects.create(**validated_data)
    #     test_case_group.test_case_merge.set(**test_case_merge)
    #     return test_case_group


class ApiRequestResultModelSerializer(BaseNestedFieldsModelSerializer):
    class Meta:
        model = ApiRequestResult
        fields = '__all__'


class TestCaseResultModelSerializer(BaseModelSerializer):
    api_request_result_list = ApiRequestResultModelSerializer(many=True, required=False)
    result_status = serializers.BooleanField(read_only=True)

    class Meta:
        model = TestCaseResult
        fields = '__all__'


class TestCaseGroupResultModelSerializer(BaseModelSerializer):
    test_result_list = TestCaseResultModelSerializer(many=True, required=False)
    result_status = serializers.BooleanField(read_only=True)

    class Meta:
        model = TestCaseGroupResult
        fields = '__all__'


class TestCaseProcessorModelSerializer(BaseModelSerializer):
    class Meta:
        model = TestCaseProcessor
        fields = '__all__'


class ApiInfoAddRequestHeaderListSerializer(serializers.Serializer):
    project_id = serializers.IntegerField()
    request_header_list = serializers.ListField(child=serializers.JSONField())


class TestCaseStepReqSerializer(BaseModelSerializer):
    test_case_processor_list = TestCaseProcessorModelSerializer(many=True, required=False)
    env_id = serializers.IntegerField(required=False)

    # 反序列化时，json字符串改为json格式返回
    request_header = serializers.SerializerMethodField(required=False)
    request_assert = serializers.SerializerMethodField(required=False)
    request_param = serializers.SerializerMethodField(required=False)
    request_data_params = serializers.SerializerMethodField(required=False)
    parameter_extraction = serializers.SerializerMethodField(required=False)

    class Meta:
        model = TestCaseStep  # 注意这里我们使用基础模型，但序列化器是为了ApiTestCaseStepReq设计的
        fields = '__all__'  # 只列出你需要的字段

    def get_request_header(self, obj):
        try:
            return json.loads(obj.request_header) if obj.request_header else []
        except json.JSONDecodeError:
            return []  # 或者抛出异常，或者返回默认值

    def get_request_assert(self, obj):
        try:
            return json.loads(obj.request_assert) if obj.request_assert else []
        except json.JSONDecodeError:
            return []  # 或者抛出异常，或者返回默认值

    def get_request_param(self, obj):
        try:
            return json.loads(obj.request_param) if obj.request_param else []
        except json.JSONDecodeError:
            return []  # 或者抛出异常，或者返回默认值

    def get_request_data_params(self, obj):
        try:
            return json.loads(obj.request_data_params) if obj.request_data_params else []
        except json.JSONDecodeError:
            return []  # 或者抛出异常，或者返回默认值

    def get_parameter_extraction(self, obj):
        try:
            return json.loads(obj.parameter_extraction) if obj.parameter_extraction else []
        except json.JSONDecodeError:
            return []  # 或者抛出异常，或者返回默认值


class TestCaseInGroupSerializer(serializers.ModelSerializer):
    case_list = TestCaseModelSerializer(source='test_case_merge', many=True, read_only=True)
    group_id = serializers.IntegerField(source='id', read_only=True)

    class Meta:
        model = TestCaseGroup
        fields = ['group_id', 'name', 'case_list']


class TestCaseGroupCreateUpdateSerializer(serializers.ModelSerializer):
    # 假设groupId不是TestCaseGroup模型的主键，而是另一个字段或用于标识要操作的组
    group_id = serializers.IntegerField(write_only=True)  # 仅在写入时使用
    test_case_ids = serializers.ListField(child=serializers.IntegerField(), write_only=True)  # 测试用例ID列表

    class Meta:
        model = TestCaseGroup
        fields = ['group_id', 'test_case_ids']  # 这里不包括其他TestCaseGroup字段，因为它们可能不是通过此序列化器设置的

    def create(self, validated_data):
        # 假设groupId是TestCaseGroup的一个字段，用于标识组（如果不是主键）
        group_id = validated_data.pop('group_id')
        # 查找或创建TestCaseGroup实例（取决于你的业务逻辑）
        group, _ = TestCaseGroup.objects.get_or_create(id=group_id)  # 如果groupId是主键
        # 或者，如果groupId不是主键，你可能需要基于其他字段来查找或创建TestCaseGroup实例
        # 获取testCaseIds并关联到TestCaseGroup
        test_case_ids = validated_data.pop('test_case_ids')
        test_cases = TestCase.objects.filter(id__in=test_case_ids)
        group.test_case_merge.set(test_cases)

        return group

    def update(self, instance, validated_data):
        # 与create方法类似，但你需要先获取group_id和test_case_ids
        group_id = validated_data.pop('group_id')
        # 验证传入的group_id是否与instance匹配（如果需要）
        # ...
        test_case_ids = validated_data.pop('test_case_ids')
        test_cases = TestCase.objects.filter(id__in=test_case_ids)
        for test_case in test_cases:
            instance.test_case_merge.add(test_case)

        # 如果需要更新其他字段，可以从validated_data中获取并应用到instance上
        # ...
        return instance


class FileUploadSerializer(serializers.Serializer):
    file = serializers.FileField()
    project_id = serializers.IntegerField()
    url = serializers.CharField()
    env_id = serializers.IntegerField()
    base_path = serializers.CharField()


class UploadByUrlSerializer(serializers.Serializer):
    import_url = serializers.URLField(required=True)
    project_id = serializers.IntegerField(required=True)
    url = serializers.CharField(required=True)
    base_path = serializers.CharField(required=True)
    env_id = serializers.IntegerField(required=True)
